package package1;

import javax.swing.JPanel;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Shape;
import java.util.ArrayList;
import java.util.Iterator;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
import java.awt.geom.*;
import java.awt.FontMetrics;
import java.lang.Double;
import java.math.BigDecimal;
import java.math.MathContext;
import java.math.RoundingMode;
import java.awt.Polygon;

@SuppressWarnings("unused")
public class Plotter2d extends JPanel
{
	Plotter2d plotter;
	
	private static final long serialVersionUID = 1L;
	private ArrayList<Line2D.Double> axis = new ArrayList<Line2D.Double>();
	private ArrayList<Point2D.Double> ticksX = new ArrayList<Point2D.Double>();
	private ArrayList<Point2D.Double> ticksY = new ArrayList<Point2D.Double>();
	private ArrayList<Point2D.Double> labelsX = new ArrayList<Point2D.Double>();
	private ArrayList<Point2D.Double> labelsY = new ArrayList<Point2D.Double>();
	private ArrayList<Function> functions = new ArrayList<Function>();
	
	private int width, height;
	private double xRange1 = -10, xRange2 = 10, xRatio;
	private double yRange1 = -10, yRange2 = 10, yRatio;
	private double xTicksSpacing = 0.1, yTicksSpacing = 0.1;
	private double xLabelsSpacing = 0.2, yLabelsSpacing = 0.2;
	private int tickSize = 10;
	
	private Color axisColor;
	private Color tickColor;
	private Color labelColor;
	
	private boolean freeAxis = true;

	Plotter2d(int width, int height)
	{
		this.plotter = this;
		
		this.width = width;
		this.height = height;

		this.setLayout(null);
		this.setBounds(0, 0, width, height);
		this.setDoubleBuffered(true);
	
		this.addMouseMotionListener(new onMouseDrag());
		this.addMouseWheelListener(new onMouseWheel());
		
		this.setAxisColor(Color.black);
		this.setTicksColor(Color.black);
		this.setLabelColor(Color.yellow);
	}
	
	public void setRange(double xRange1, double xRange2, double yRange1, double yRange2)
	{
		this.xRange1 = xRange1;
		this.xRange2 = xRange2;
		this.yRange1 = yRange1;
		this.yRange2 = yRange2;
		
		this.xRatio = this.width / (xRange2 - xRange1);
		this.yRatio = this.height / (yRange2 - yRange1);
		
		this.resetAuxComponents();
	}
	
	public void setFreeAxis(boolean freeAxis)
	{
		this.freeAxis = freeAxis;
		
		this.resetAuxComponents();
	}
	
	public void setTicks(double xTicksSpacing, double yTicksSpacing, int tickSize)
	{
		this.xTicksSpacing = xTicksSpacing;
		this.yTicksSpacing = yTicksSpacing;
		this.tickSize = tickSize;
		
		if(!this.ticksX.isEmpty() || !this.ticksY.isEmpty())
		{
			this.ticksX.clear();
			this.ticksY.clear();
		}

		this.addTicks();
	}
	
	public void setTicksSize(int ticksSize)
	{
		this.tickSize = ticksSize;
	}
	
	public void setLabels(double xLabelsSpacing, double yLabelsSpacing)
	{
		this.xLabelsSpacing = xLabelsSpacing;
		this.yLabelsSpacing = yLabelsSpacing;
		
		if(!this.labelsX.isEmpty() || !this.labelsY.isEmpty())
		{
			this.labelsX.clear();
			this.labelsY.clear();
		}
		
		this.addLabels();
	}
	
	public void setLabelColor(Color labelColor)
	{
		this.labelColor = labelColor;
	}
	
	public void setTicksColor(Color tickColor)
	{
		this.tickColor = tickColor;
	}
	
	public void setAxisColor(Color axisColor)
	{
		this.axisColor = axisColor;
	}
	
	public void paint(Graphics graphic)
	{
		super.paint(graphic);
		
		Graphics2D graphics2D = (Graphics2D)(graphic);
		
		Iterator<Line2D.Double> axisIt = this.axis.iterator();
		Iterator<Point2D.Double> ticksXIt = this.ticksX.iterator();
		Iterator<Point2D.Double> ticksYIt = this.ticksY.iterator();
		Iterator<Point2D.Double> labelsXIt = this.labelsX.iterator();
		Iterator<Point2D.Double> labelsYIt = this.labelsY.iterator();
		Iterator<Function> functionIt = this.functions.iterator();
		
		// Draws the axis.
		while(axisIt.hasNext())
		{
			Line2D.Double axis = axisIt.next();
			
			Line2D.Double axisDraw = this.getPixPos(axis);
			
			graphics2D.setColor(this.axisColor);
			graphics2D.draw(axisDraw);
		}
		
		// Draws X the ticks.
		while(ticksXIt.hasNext())
		{
			Point2D.Double tickXPos = ticksXIt.next();
			
			Point2D.Double p1Draw = this.getPixPos(tickXPos);
			Point2D.Double p2Draw = this.getPixPos(tickXPos);
			
			p1Draw.y -= this.tickSize / 2;
			p2Draw.y += this.tickSize / 2;
			
			Line2D.Double tick = new Line2D.Double(p1Draw, p2Draw);
			
			graphics2D.setColor(this.tickColor);
			graphics2D.draw(tick);
		}
		
		// Draws Y the ticks.
		while(ticksYIt.hasNext())
		{
			Point2D.Double tickYPos = ticksYIt.next();
			
			Point2D.Double p1Draw = this.getPixPos(tickYPos);
			Point2D.Double p2Draw = this.getPixPos(tickYPos);
			
			p1Draw.x -= this.tickSize / 2;
			p2Draw.x += this.tickSize / 2;
			
			Line2D.Double tick = new Line2D.Double(p1Draw, p2Draw);
			
			graphics2D.setColor(this.tickColor);
			graphics2D.draw(tick);
		}
		
		 // Draws the X tick's labels.
		while(labelsXIt.hasNext())
		{
			Point2D.Double labelXPos = labelsXIt.next();
			Double value = new Double(labelXPos.x);
			BigDecimal valueRounded = new BigDecimal(value);
			MathContext precision = new MathContext(2, RoundingMode.HALF_UP);
			valueRounded = valueRounded.round(precision);
			
			String labelString = valueRounded.toString();
			
			FontMetrics fontMetrics = graphics2D.getFontMetrics();
			int labelHeight = fontMetrics.getHeight();
			int labelWidth = fontMetrics.stringWidth(labelString);
			
			Point2D.Double labelDraw = this.getPixPos(labelXPos);
			labelDraw.x -= labelWidth / 2;
			labelDraw.y += labelHeight + (this.tickSize / 2);
			
			graphics2D.setColor(this.labelColor);
			graphics2D.drawString(labelString, (int)labelDraw.x, (int)labelDraw.y);
		}
		
		 // Draws the Y tick's labels.
		while(labelsYIt.hasNext())
		{
			Point2D.Double labelYPos = labelsYIt.next();
			Double value = new Double(labelYPos.y);
			BigDecimal valueRounded = new BigDecimal(value);
			MathContext precision = new MathContext(2, RoundingMode.HALF_UP);
			valueRounded = valueRounded.round(precision);
			
			String labelString = valueRounded.toString();
			
			FontMetrics fontMetrics = graphics2D.getFontMetrics();
			int labelHeight = fontMetrics.getHeight();
			int labelWidth = fontMetrics.stringWidth(labelString);
			
			Point2D.Double labelDraw = this.getPixPos(labelYPos);
			labelDraw.x -= this.tickSize + labelWidth;
			labelDraw.y += labelHeight / 2;
			
			graphics2D.drawString(labelString, (int)labelDraw.x, (int)labelDraw.y);
		}
		
		while(functionIt.hasNext())
		{
			Function function = functionIt.next();
			
			if(function.isHide())
			{
				continue;
			}
			
			Iterator<Point2D.Double> pointIt = function.getPoints().iterator();
			
			// Draws each point.
			while(pointIt.hasNext())
			{
				Point2D.Double point = pointIt.next();
				
				Point2D.Double pointDraw = this.getPixPos(point);
				int x = (int)pointDraw.getX() - function.getPointSize() / 2;
				int y = (int)pointDraw.getY() - function.getPointSize() / 2;
				
				Ellipse2D.Double ellipseDraw = new Ellipse2D.Double(x, y, function.getPointSize(), function.getPointSize());
				graphics2D.setColor(function.getPointColor());
				
				if(function.isFillPoint())
				{
					graphics2D.fill(ellipseDraw);
				}
				
				else
				{
					graphics2D.draw(ellipseDraw);
				}
			}
			
			pointIt = function.getPoints().iterator();
			
			// Draws the lines between the points.
			if(pointIt.hasNext() && function.isShowLine())
			{
				graphics2D.setColor(function.getLineColor());
				
				Point2D.Double p1 = pointIt.next();
				Point2D.Double p1Draw = this.getPixPos(p1);
				
				while(pointIt.hasNext())
				{
					Point2D.Double p2 = pointIt.next();
					Point2D.Double p2Draw = this.getPixPos(p2);
					
					Line2D.Double line = new Line2D.Double(p1Draw, p2Draw);
					graphics2D.draw(line);
	
					p1Draw = p2Draw;
				}
			}
			
			// Draws the trapezoids below the function. 
			pointIt = function.getPoints().iterator();
			
			if(pointIt.hasNext() && function.isShowArea())
			{	
				graphics2D.setColor(function.getAreaColor());
				
				Point2D.Double p1 = pointIt.next();
				
				while(pointIt.hasNext())
				{
					Point2D.Double p2 = null;
					
					for(int i = 0; i < function.getAreaStep() && pointIt.hasNext(); i++)
					{
						p2 = pointIt.next();
					}
					
					Point2D.Double p1Draw = this.getPixPos(p1);
					Point2D.Double p2Draw = this.getPixPos(p2);
					
					Point2D.Double p1x = new Point2D.Double(p1.getX(), 0);
					Point2D.Double p1xDraw = this.getPixPos(p1x);
					
					Point2D.Double p2x = new Point2D.Double(p2.getX(), 0);
					Point2D.Double p2xDraw = this.getPixPos(p2x);
					
					Polygon polygon = new Polygon();
					polygon.addPoint((int)p1Draw.getX(), (int)p1Draw.getY());
					polygon.addPoint((int)p1xDraw.getX(), (int)p1xDraw.getY());
					polygon.addPoint((int)p2xDraw.getX(), (int)p2xDraw.getY());
					polygon.addPoint((int)p2Draw.getX(), (int)p2Draw.getY());
					
					if(function.isFillArea())
					{
						graphics2D.fillPolygon(polygon);
					}
					
					else
					{
						graphics2D.drawPolygon(polygon);
					}
					
					p1 = p2;
				}
			}
		}
	}
	
	// Gets the on screen pixel position, given an x and y.
	private Point2D.Double getPixPos(double x, double y)
	{	
		double xDraw = (x - this.xRange1) * this.xRatio;
		double yDraw = (this.yRange2 - y) * this.yRatio;

		Point2D.Double pointDraw = new Point2D.Double(xDraw, yDraw);
		return pointDraw;
	}
	
	// Gets the on screen pixel position, given a Point2D.Double.
	private Point2D.Double getPixPos(Point2D.Double point)
	{
		double xDraw = (point.getX() - this.xRange1) * this.xRatio;
		double yDraw  = (this.yRange2 - point.getY()) * this.yRatio;
		
		Point2D.Double pointDraw = new Point2D.Double(xDraw, yDraw);
		return pointDraw;
	}
	
	// Gets the on screen pixel position of a line, given a Line2D.Double.
	private Line2D.Double getPixPos(Line2D.Double line)
	{
		Point2D.Double p1 = (Point2D.Double)line.getP1();
		Point2D.Double p2 = (Point2D.Double)line.getP2();
		
		Point2D.Double p1Draw = this.getPixPos(p1);
		Point2D.Double p2Draw = this.getPixPos(p2);
		
		Line2D.Double lineDraw = new Line2D.Double(p1Draw, p2Draw);
		return lineDraw;
	}
	
	private Point2D.Double getRealPos(int x, int y)
	{
		double xPos = x * (this.xRange2 - this.xRange1) / this.width;
		double yPos = y * (this.yRange2 - this.yRange1) / this.height;
		
		Point2D.Double realPos = new Point2D.Double(xPos, yPos);
		return realPos;
	}
	
	private void addAxis()
	{
		double x1_xAxis = this.xRange1;
		double y1_xAxis;
		if(this.freeAxis){ y1_xAxis = 0; } // If the axis is free, makes the X axis be placed always on y = 0.
		else { y1_xAxis = (this.yRange2 - this.yRange1) / 2 + this.yRange1; } // If not, it is always placed on the middle of the y range.
		
		double x2_xAxis = this.xRange2;
		double y2_xAxis;
		if(this.freeAxis){ y2_xAxis = 0; } // If the axis is free, makes the X axis be placed always on y = 0.
		else { y2_xAxis = (this.yRange2 - this.yRange1) / 2 + this.yRange1; } // If not, it is always placed on the middle of the y range.
		
		double x1_yAxis;
		if(this.freeAxis){ x1_yAxis = 0; } // If the axis is free, makes the Y axis be placed always on x = 0.
		else { x1_yAxis = (this.xRange2 - this.xRange1) / 2 + this.xRange1; } // If not, it is always placed on the middle of the x range.
		double y1_yAxis = this.yRange1;
		
		double x2_yAxis;
		if(this.freeAxis) { x2_yAxis = 0; } // If the axis is free, makes the Y axis be placed always on x = 0.
		else { x2_yAxis = (this.xRange2 - this.xRange1) / 2 + this.xRange1; } // If not, it is always placed on the middle of the x range.
		double y2_yAxis = this.yRange2;
		
		Line2D.Double xAxis = new Line2D.Double(x1_xAxis, y1_xAxis, x2_xAxis, y2_xAxis);
		Line2D.Double yAxis = new Line2D.Double(x1_yAxis, y1_yAxis, x2_yAxis, y2_yAxis);
		
		this.axis.add(xAxis);
		this.axis.add(yAxis);
	}
	
	private void addTicks()
	{
		// Positive X axis.
		if(this.freeAxis)
		{
			for(int i = 0; i * this.xTicksSpacing < Math.abs(this.xRange2); i++)
			{
				double xPos = i * this.xTicksSpacing;
				double middleY = 0;
				
				Point2D.Double tick = new Point2D.Double(xPos, middleY);

				this.ticksX.add(tick);
			}
			
			// Negative X axis.
			for(int i = 1; i * this.xTicksSpacing < Math.abs(this.xRange1); i++)
			{
				double xPos = - i * this.xTicksSpacing;
				double middleY = 0;
				
				Point2D.Double tick = new Point2D.Double(xPos, middleY);
				
				this.ticksX.add(tick);
			}
			
			// Positive Y axis.
			for(int i = 0; i * this.yTicksSpacing < Math.abs(this.yRange2); i++)
			{
				double yPos = i * this.yTicksSpacing;
				double middleX = 0;
				
				Point2D.Double tick = new Point2D.Double(middleX, yPos);

				this.ticksY.add(tick);
			}
			
			// Negative Y axis.
			for(int i = 0; i * this.yTicksSpacing < Math.abs(this.yRange1); i++)
			{
				double yPos = - i * this.yTicksSpacing;
				double middleX = 0;
				
				Point2D.Double tick = new Point2D.Double(middleX, yPos);
				
				this.ticksY.add(tick);
			}
		}
		
		else
		{
			// Positive X axis.
			for(int i = 1; (i * this.xTicksSpacing + (this.xRange2 - this.xRange1) / 2 + this.xRange1) < this.xRange2; i++)
			{
				double xPos = i * this.xTicksSpacing + (this.xRange2 - this.xRange1) / 2 + this.xRange1;
				double middleY = (this.yRange2 - this.yRange1) / 2 + this.yRange1;
				
				Point2D.Double tick = new Point2D.Double(xPos, middleY);
	
				this.ticksX.add(tick);
			}
			
			// Negative X axis.
			for(int i = 1; ((this.xRange2 - this.xRange1) / 2) + this.xRange1 - (i * this.xTicksSpacing) > this.xRange1; i++)
			{
				double xPos = ((this.xRange2 - this.xRange1) / 2) + this.xRange1 - (i * this.xTicksSpacing);
				double middleY = (this.yRange2 - this.yRange1) / 2 + this.yRange1;
				
				Point2D.Double tick = new Point2D.Double(xPos, middleY);
				
				this.ticksX.add(tick);
			}
			
			// Positive Y axis.
			for(int i = 1; (i * this.yTicksSpacing + (this.yRange2 - this.yRange1) / 2 + this.yRange1)  < this.yRange2; i++)
			{
				double yPos = i * this.yTicksSpacing + (this.yRange2 - this.yRange1) / 2 + this.yRange1;
				double middleX = (this.xRange2 - this.xRange1) / 2 + this.xRange1;
				
				Point2D.Double tick = new Point2D.Double(middleX, yPos);
	
				this.ticksY.add(tick);
			}
			
			// Negative Y axis.
			for(int i = 1; ((this.yRange2 - this.yRange1) / 2) + this.yRange1 - (i * this.yTicksSpacing) > this.yRange1; i++)
			{
				double yPos = ((this.yRange2 - this.yRange1) / 2) + this.yRange1 - (i * this.yTicksSpacing);
				double middleX = (this.xRange2 - this.xRange1) / 2 + this.xRange1;
				
				Point2D.Double tick = new Point2D.Double(middleX, yPos);
				
				this.ticksY.add(tick);
			}
		}
	}
	
	private void addLabels()
	{
		if(this.freeAxis)
		{
			// Positive X axis.
			for(int i = 0; i * this.xLabelsSpacing < Math.abs(this.xRange2); i++)
			{
				double xPos = i * this.xLabelsSpacing;
				double middleY = 0;
				
				Point2D.Double label = new Point2D.Double(xPos, middleY);

				this.labelsX.add(label);
			}
			
			// Negative X axis.
			for(int i = 1; i * this.xLabelsSpacing < Math.abs(this.xRange1); i++)
			{
				double xPos = - i * this.xLabelsSpacing;
				double middleY = 0;
				
				Point2D.Double label = new Point2D.Double(xPos, middleY);
				
				this.labelsX.add(label);
			}
			
			// Positive Y axis.
			for(int i = 0; i * this.yLabelsSpacing < Math.abs(this.yRange2); i++)
			{
				double yPos = i * this.yLabelsSpacing;
				double middleX = 0;
				
				Point2D.Double label = new Point2D.Double(middleX, yPos);

				this.labelsY.add(label);
			}
			
			// Negative Y axis.
			for(int i = 1; i * this.yLabelsSpacing < Math.abs(this.yRange1); i++)
			{
				double yPos = - i * this.yLabelsSpacing;
				double middleX = 0;

				Point2D.Double label = new Point2D.Double(middleX, yPos);
				
				this.labelsY.add(label);
			}
		}
		
		else
		{
			// Positive X axis.
			for(int i = 1; (i * this.xLabelsSpacing + (this.xRange2 - this.xRange1) / 2 + this.xRange1) < this.xRange2; i++)
			{
				double xPos = i * this.xLabelsSpacing + (this.xRange2 - this.xRange1) / 2 + this.xRange1;
				double middleY = (this.yRange2 - this.yRange1) / 2 + this.yRange1;
				
				Point2D.Double label = new Point2D.Double(xPos, middleY);

				this.labelsX.add(label);
			}
			
			// Negative X axis.
			for(int i = 1; ((this.xRange2 - this.xRange1) / 2) + this.xRange1 - (i * this.xLabelsSpacing) > this.xRange1; i++)
			{
				double xPos = ((this.xRange2 - this.xRange1) / 2) + this.xRange1 - (i * this.xLabelsSpacing);
				double middleY = (this.yRange2 - this.yRange1) / 2 + this.yRange1;
				
				Point2D.Double label = new Point2D.Double(xPos, middleY);
				
				this.labelsX.add(label);
			}
			
			// Positive Y axis.
			for(int i = 1; (i * this.yLabelsSpacing + (this.yRange2 - this.yRange1) / 2 + this.yRange1)  < this.yRange2; i++)
			{
				double yPos = i * this.yLabelsSpacing + (this.yRange2 - this.yRange1) / 2 + this.yRange1;
				double middleX = (this.xRange2 - this.xRange1) / 2 + this.xRange1;
				
				Point2D.Double label = new Point2D.Double(middleX, yPos);

				this.labelsY.add(label);
			}
			
			// Negative Y axis.
			for(int i = 1; ((this.yRange2 - this.yRange1) / 2) + this.yRange1 - (i * this.yLabelsSpacing) > this.yRange1; i++)
			{
				double yPos = ((this.yRange2 - this.yRange1) / 2) + this.yRange1 - (i * this.yLabelsSpacing);
				double middleX = (this.xRange2 - this.xRange1) / 2 + this.xRange1;
				
				Point2D.Double label = new Point2D.Double(middleX, yPos);
				
				this.labelsY.add(label);
			}
		}
	}
	
	public Function addFunction()
	{
		Function function = new Function();
		this.functions.add(function);
		
		return function;
	}
	
	public void removeFunction(int functionIndex)
	{
		this.functions.remove(functionIndex);
	}
	
	public Function getFunction(int functionIndex)
	{
		return this.functions.get(functionIndex);
	}
	
	private void resetAuxComponents()
	{
		if(!this.axis.isEmpty())
		{
			this.axis.clear();
		}
		
		if(!this.ticksX.isEmpty() || !this.ticksY.isEmpty())
		{
			this.ticksX.clear();
			this.ticksY.clear();
		}
		
		if(!this.labelsX.isEmpty() || !this.labelsY.isEmpty())
		{
			this.labelsX.clear();
			this.labelsY.clear();
		}
		
		this.addAxis();
		this.addTicks();
		this.addLabels();
	}
	
	class onMouseWheel implements MouseWheelListener
	{
		@Override
		public void mouseWheelMoved(MouseWheelEvent event) 
		{
			double newXRange1, newXRange2;
			double newYRange1, newYRange2;
			double newXTicksSpacing, newYTicksSpacing;
			double newXLabelSpacing, newYLabelSpacing;
			
			// Zoom in.
			if (event.getWheelRotation() < 0)
			{
				newXRange1 = plotter.xRange1 + (plotter.xRange2 - plotter.xRange1) / 30;
				newXRange2 = plotter.xRange2 - (plotter.xRange2 - plotter.xRange1) / 30;
				
				newYRange1 = plotter.yRange1 + (plotter.yRange2 - plotter.yRange1) / 30;
				newYRange2 = plotter.yRange2 - (plotter.yRange2 - plotter.yRange1) / 30;
				
				newXTicksSpacing = plotter.xTicksSpacing - plotter.xTicksSpacing / 15;
				newYTicksSpacing = plotter.yTicksSpacing - plotter.yTicksSpacing / 15;
				
				newXLabelSpacing = plotter.xLabelsSpacing - plotter.xLabelsSpacing / 15;
				newYLabelSpacing = plotter.yLabelsSpacing - plotter.yLabelsSpacing / 15;
			}
			
			// Zoom out.
			else
			{
				newXRange1 = plotter.xRange1 - (plotter.xRange2 - plotter.xRange1) / 30;
				newXRange2 = plotter.xRange2 + (plotter.xRange2 - plotter.xRange1) / 30;
				
				newYRange1 = plotter.yRange1 - (plotter.yRange2 - plotter.yRange1) / 30;
				newYRange2 = plotter.yRange2 + (plotter.yRange2 - plotter.yRange1) / 30;
				
				newXTicksSpacing = plotter.xTicksSpacing + plotter.xTicksSpacing / 15;
				newYTicksSpacing = plotter.yTicksSpacing + plotter.yTicksSpacing / 15;
				
				newXLabelSpacing = plotter.xLabelsSpacing + plotter.xLabelsSpacing / 15;
				newYLabelSpacing = plotter.yLabelsSpacing + plotter.yLabelsSpacing / 15;
			}
			
			plotter.setRange(newXRange1, newXRange2, newYRange1, newYRange2);
			plotter.setTicks(newXTicksSpacing, newYTicksSpacing, plotter.tickSize);
			plotter.setLabels(newXLabelSpacing, newYLabelSpacing);
			plotter.repaint();
		}
	}
	
	class onMouseDrag implements MouseMotionListener
	{
		int oldX, oldY;

		@Override
		public void mouseDragged(MouseEvent event) 
		{
			int xDif = this.oldX - event.getX();
			int yDif = this.oldY - event.getY();
			
			Point2D.Double realPosDif = plotter.getRealPos(xDif, yDif);
			
			double newXRange1 = plotter.xRange1 + realPosDif.x;
			double newXRange2 = plotter.xRange2 + realPosDif.x;
			double newYRange1 = plotter.yRange1 - realPosDif.y;
			double newYRange2 = plotter.yRange2 - realPosDif.y;
			
			plotter.setRange(newXRange1, newXRange2, newYRange1, newYRange2);
			plotter.repaint();
			
			this.oldX = event.getX();
			this.oldY = event.getY();
		}

		@Override
		public void mouseMoved(MouseEvent event) 
		{	
			this.oldX = event.getX();
			this.oldY = event.getY();
		}
	}
}
